﻿using _3DTools;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;

namespace CPPEI.WPF
{
    public partial class ViewContainer : Grid
    {
        //private List<PopViewDecorator> _popViews;
        private View _currentView;
        private List<View> _history;


        Grid _container;


        //MeshGeometry3D x:Key="PlaneMesh" Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0" TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"

        private ViewQueue _viewQueue = new ViewQueue();

        private View _outView;

        public ViewQueue ViewQueue
        {
            get
            {
                return _viewQueue;
            }
        }

        public View CurrentView
        {
            get
            {
                return _currentView;
            }
        }
        
        public ViewContainer()
        {
            //_popViews = new List<PopViewDecorator>();
            _history = new List<View>();

        }

        public void Near()
        {
            PerspectiveCamera camera = _3dViewport.Camera as PerspectiveCamera;
            camera.Position = new Point3D(0, 0, camera.Position.Z + 5.0d);

            camera.LookDirection = new Vector3D(0, 0, camera.Position.Z / -1.0d);
        }

        System.Threading.Thread _thread;

        /// <summary>
        /// 切换视图
        /// </summary>
        /// <param name="view"></param>
        private void SwitchView(View view)
        {
            Init3D();

            if (_viewQueue.HasNode())
            {
                _viewQueue.Enqueue(ViewActionBehavior.Open, view, null);
            }
            else
            {
                View inView = null;
                View outView = null;
                // 清除历史视图
                if (_history != null)
                {
                    for (int index = 0; index < _history.Count; index++)
                    {
                        _history[index].Deactive();
                    }
                    _history.Clear();
                }

                if (_currentView != null)
                {
                    outView = _currentView;
                    _container.Children.Remove(_currentView);
                }
                _container.Children.Add(view);
                _currentView = view;
                inView = view;

                if (outView != null)
                {
                    outView.Deactive();
                }
                // 激活视图
                inView.Active();
            }
        }

        public void SwitchView(View view, SwitchEffect switchEffect)
        {
            Init3D();

            if (_viewQueue.HasNode())
            {
                Debug.WriteLine("Not Head enqueue");
                _viewQueue.Enqueue(ViewActionBehavior.Open, view, switchEffect);
            }
            else
            {
                _viewQueue.Enqueue(ViewActionBehavior.Open, view, switchEffect);
                View inView = null;
                View outView = null;

                // 清除历史视图
                if (_history != null)
                {
                    for (int index = 0; index < _history.Count; index++)
                    {
                        _history[index].Deactive();
                    }
                    _history.Clear();
                }

                if (_currentView != null)
                {
                    _container.Children.Remove(_currentView);
                    _currentView.Deactive();

                    outView = _currentView;
                }
                _container.Children.Add(view);
                _currentView = view;

                inView = view;

                for (int index = 0; index < this._3dVisual3dList.Count; index++)
                {
                    _3dViewport.Children.Remove(this._3dVisual3dList[index]);
                }
                this._3dVisual3dList.Clear();

                _switchEffect = switchEffect;

                _outView = outView;
                Debug.WriteLine("head Thread start");
                _thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(running));
                _thread.Start(new object[] { inView, outView });
            }
        }

        private void running(object p)
        {
            object[] viewArr = (object[])p;

            View inView = viewArr[0] as View;
            View outView = viewArr[1] as View;

            int excpact = 0;
            int current = 0;

            if (inView != null)
            {
                excpact++;
            }
            if (outView != null)
            {
                excpact++;
            }

            while (true)
            {
                if (inView != null && inView.Snapshot != null)
                {
                    this.Dispatcher.Invoke(() =>
                    {
                        ModelVisual3D iv3d = _switchEffect.BuildIn(this._3dPlaneMesh, inView, _3dStorybard, _switchEffectDuration);
                        _3dViewport.Children.Add(iv3d);
                        this._3dVisual3dList.Add(iv3d);
                    });
                    current++;
                }
                else if (outView != null && outView.Snapshot != null)
                {
                    this.Dispatcher.Invoke(() =>
                    {
                        ModelVisual3D iv3d = _switchEffect.BuildOut(this._3dPlaneMesh, outView, _3dStorybard, _switchEffectDuration);
                        _3dViewport.Children.Add(iv3d);
                        this._3dVisual3dList.Add(iv3d);
                    });
                    current++;
                }
                if (current == excpact)
                {
                    this.Dispatcher.Invoke(() =>
                    {
                        this._3dPanel.Visibility = System.Windows.Visibility.Visible;
                        this._container.Visibility = System.Windows.Visibility.Hidden;
                        _3dIsStoryboardRunning = true;
                        _3dStorybard.Begin(this, true);
                        Debug.WriteLine("动画开始");
                    });
                    break;
                }
            }
            Debug.WriteLine("Thread exit");
        }

        void sb_Completed(object sender, EventArgs e)
        {
            Debug.WriteLine("动画结束, children:{0}",  _3dStorybard.Children.Count);

            for (int index = 0; index < this._3dVisual3dList.Count; index++)
            {
                _3dViewport.Children.Remove(this._3dVisual3dList[index]);
            }
            this._3dVisual3dList.Clear();
            _3dStorybard.Children.Clear();

            // 拿掉当前在运行的节点
            // 拿出一个节点
            ViewQueueNode nextNode = _viewQueue.GetNextRemoveCurrent();
            Debug.WriteLine("动画结束, _viewQueue children:{0}", _viewQueue.Count);
            if (nextNode != null)
            {
                DoQueueNode(nextNode);
            }
            else
            {
                this._3dPanel.Visibility = System.Windows.Visibility.Hidden;
                this._container.Visibility = System.Windows.Visibility.Visible;

                if (_outView != null)
                {
                    _outView.Deactive();
                }
                // 激活当前视图
                _currentView.Active();
            }
        }

        private void DoQueueNode(ViewQueueNode node)
        {
            if (node.Behavior == ViewActionBehavior.Open)
            {
                TrueSwitchView(node.View, node.SwitchEffect);
            }
        }

        private void TrueSwitchView(View view, SwitchEffect switchEffect)
        {
            View inView = null;
            View outView = null;

            // 清除历史视图
            if (_history != null)
            {
                for (int index = 0; index < _history.Count; index++)
                {
                    _history[index].Deactive();
                }
                _history.Clear();
            }

            if (_currentView != null)
            {
                _container.Children.Remove(_currentView);
                _currentView.Deactive();

                outView = _currentView;
            }
            _container.Children.Add(view);
            _currentView = view;

            inView = view;

            for (int index = 0; index < this._3dVisual3dList.Count; index++)
            {
                _3dViewport.Children.Remove(this._3dVisual3dList[index]);
            }
            this._3dVisual3dList.Clear();

            _switchEffect = switchEffect;

            _thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(running));
            _thread.Start(new object[] { inView, outView });
        }

        /// <summary>
        /// 切换出子视图
        /// </summary>
        /// <param name="subView"></param>
        public void SwitchSubView(View subView)
        {
            if (_currentView == null)
            {
                return;
            }
            _history.Add(_currentView);

            _container.Children.Remove(_currentView);
            //_currentView.Deactive();
            _container.Children.Add(subView);
            _currentView = subView;
        }

        /// <summary>
        /// 返回到上一级视图，通过SwitchSubView打开之后，可以调用这个
        /// </summary>
        public void Back()
        {
            if (_history.Count > 0)
            {
                _container.Children.Remove(_currentView);
                _currentView.Deactive();
                _container.Children.Add(_history.Last());
                _currentView = _history.Last();
            }
        }

        public void Remove(View view)
        {
            if (_currentView == view)
            {
                _container.Children.Remove(_currentView);
                _currentView.Deactive();
                _currentView = null;
            }
        }

        protected override void OnRenderSizeChanged(System.Windows.SizeChangedInfo sizeInfo)
        {
            Resize3d();
            base.OnRenderSizeChanged(sizeInfo);
        }
    }
}
